package com.example.springboot.controller.responseParams;

import com.example.springboot.bean.Employee;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;


/**
 * springboot支持的返回值类型 默认的是12种
 * 1 ModelAndView
 * 2 Model
 * 3 View
 * 4 ResponseEntity
 * 5 ResponseBodyEmitter
 * 6 StreamingResponseBody
 * 7 HttpEntity
 * 8 HttpHeaders
 * 9 Callable 异步
 * 10 DeferredResult异步
 * 11 AsyncTask 异步
 * 12 RequestResponseBodyMethodProcessor (标记了responseBody注解会被这个类处理)
 *  ① 利用MessageConverter进行处理，将数据写为json
 *     1 内容协商，浏览器以请求头的方式告诉服务器能接受的响应类型
 *     2 服务器根据自身的能力，决定自己需要生产的数据
 *     3 springmvc会挨个遍历消息转换器MessageConverter，看谁能处理这个返回值（看是否支持将此Class的对象，转为MediaType类型的数据）
 *          1 ByteArrayMessageConverter 进制byte类型的返回值
 *          2 StringMessageConverter 仅支持string类型的返回值
 *          3 ResourceMessageConverter 仅支持resource类型
 *          4 SourceHttpMessageConverter 支持xml
 *          5 MappingJackson2HttpMessageConverter 能支持所有的的媒体类型
 * 内容协商原理：
 *   1 判断当前响应头中是否已经有确定的媒体类型，MediaType
 *   2 通过内容协商管理器（ContentNegotiationManager）获取客户端（postman,浏览器）支持接收的内容类型，获取客户端Accept请求头字段(默认通过HeaderContentNegotiationStrategy请求头的策略)
 *   3 遍历循环当前系统的messageConverter看谁支持操作这个对象
 *   4 找到支持操作这个对象的converter,把converter支持的媒体类型统计出来
 *   5
 *
 * @Author:ChenZhangKun
 * @Date: 2021/6/16 22:52
 */
@Controller
@RequestMapping("/response")
public class ResponseParamController {
    /**
     * 测试内容协商，根据请求头返回xml和json的切换
     * 请求头：Accept:application/json 此时返回json
     * {
     *     "id": null,
     *     "lastName": "czk",
     *     "gender": 2,
     *     "email": "1052031630@qq.com",
     *     "dId": 1
     * }
     *        Accept:application/xml 此时返回xml (注意要导入jackson/xml的包)
     *        <Employee>
     *     <id/>
     *     <lastName>czk</lastName>
     *     <gender>2</gender>
     *     <email>1052031630@qq.com</email>
     *     <dId>1</dId>
     * </Employee>
     * 注意：浏览器访问会直接返回xml的原因是 其能接收的类型是text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,;q=0.8,application/signed-exchange;v=b3;q=0.9
     *  application/xml的权重最大，所以返回xml
     *  测试：自定义converter
     *   1 浏览器发请求则返回xml application/xml
     *   2 如果是ajax请求，返回json application/json
     *   3 客户端内容协商 application/czk
     * @return
     */
    @GetMapping("/em")
    @ResponseBody
    public Employee employee(){
        Employee employee = new Employee();
        employee.setdId(1);
        employee.setEmail("1052031630@qq.com");
        employee.setGender(2);
        employee.setLastName("czk");
        return employee;
    }
}
